﻿// Inner Fire 游戏引擎库
// 帧资源类
//
// Copyright (c) 2024 by 尔西大帝. All rights reserved.
//
// 这个类用于进行帧资源的操作。使CPU与GPU不需要等待同步进行操作。
//
// Author: 尔西大帝
// Email: 2670613871@qq.com
// Created: 2024-11-19

#include "frame_resource.h"

namespace ifire::dx {

FrameResource::FrameResource(
    ID3D12Device* device, const FrameResourceDesc& _desc)
    : desc(_desc), instanced_sprite(this, false) {
  HASSERT(device->CreateCommandAllocator(
      D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(allocator.GetAddressOf())));
  // 主项目有1个Pass，加上ShadowPass
  size_t pass_count = desc.PassCount + desc.ShadowPassCount;
  pass_cb =
      std::make_unique<UploadBuffer<PassConstants>>(device, pass_count, true);

  // 根据对象数量创建
  if (desc.ObjectCount > 0) {
    object_cb = std::make_unique<UploadBuffer<ObjectConstants>>(
        device, desc.ObjectCount, true);
  }
  if (desc.SkinnedObjectCount > 0) {
    skinned_cb = std::make_unique<UploadBuffer<SkinnedConstants>>(
        device, desc.SkinnedObjectCount, true);
  }
  if (desc.InstancedSprite > 0) {
    instanced_sprite_cb =
        std::make_unique<UploadBuffer<InstancedSpriteConstants>>(
            device, desc.InstancedSprite, true);
  }
  if (desc.MapBlock > 0) {
    map_block_cb = std::make_unique<UploadBuffer<InstancedSpriteConstants>>(
        device, desc.MapBlock, true);
  }

  // 根据纹理数量创建
  if (desc.MaterialCount > 0) {
    // 注意这个是结构化缓冲区，不是常量缓冲区，所以是false
    material_buffer = std::make_unique<UploadBuffer<MaterialData>>(
        device, desc.MaterialCount, false);
  }

  // 用于屏幕空间环境光遮蔽
  ssao_cb = std::make_unique<UploadBuffer<SsaoConstants>>(device, 1, true);

  // 用于UI
  // 这个也不是常量缓冲区，所以false，不需要对齐
  if (desc.UICount > 0) {
    ui_cb = std::make_unique<UploadBuffer<UIInstancedData>>(
        device, desc.UICount, false);
  }
  if (desc.TextCount > 0) {
    text_cb = std::make_unique<UploadBuffer<UIInstancedData>>(
        device, desc.TextCount, false);
  }
}

} // namespace ifire::dx
